import 'dart:io';
import 'package:image/image.dart';
import 'package:jhjj/judge_list.dart';

void jj() {
    // 加载图片
    final imageFile = File('/temp/t1/a.jpg');
    final image = decodeImage(imageFile.readAsBytesSync())!;

    // 参数配置
    const maxVolume = 1000;
    var backgroundColor = ColorRgb8(255, 255, 255);
    const buyThreshold = 1.3;
    const sellThreshold = 1.3;

    var volumeList = <VolumeResult>[];
    for (int x = 0; x < image.width; x++) {
        final result = _analyzeColumn(
            image,
            x,
            maxVolume,
            backgroundColor,
            buyThreshold,
            sellThreshold,
        );
        volumeList.add( result );

        print('时间: ${x.toString().padLeft(3)} | '
            '未成交-买: ${result.unexecutedBuy.toString().padLeft(4)}, '
            '卖: ${result.unexecutedSell.toString().padLeft(4)} | '
            '已成交-买: ${result.executedBuy.toString().padLeft(4)}, '
            '卖: ${result.executedSell.toString().padLeft(4)}');
    }

    volumeList = purgeList( volumeList );

    /*
1.未成交买盘逐渐增大，同时已成交买盘或已成交卖盘未同步增大。如果满足该条件则打印"good_1";
2.未成交卖盘逐渐减少，同时已成交买盘或已成交卖盘逐渐增大。如果满足该条件则打印"good_2";
     */
    var r1 = checkVolumeTrendIncreasing(volumeList, checkBuy:true, checkExecuted:false);
    if ( r1 && !checkVolumeTrendIncreasing(volumeList, checkBuy:true, checkExecuted: true)) {
        print('good 1');
        return;
    }
    if ( r1 && !checkVolumeTrendIncreasing(volumeList, checkBuy:false, checkExecuted: true)) {
        print('good 2');
        return;
    }

    var r2 = ! checkVolumeTrendIncreasing(volumeList, checkBuy:false, checkExecuted:false);
    if (r2 && checkVolumeTrendIncreasing(volumeList, checkBuy:true, checkExecuted: true)) {
        print('good 3');
        return;
    }
    if (r2 && checkVolumeTrendIncreasing(volumeList, checkBuy:false, checkExecuted: true)) {
        print('good 4');
        return;
    }
}

class VolumeResult {
    int unexecutedBuy;
    int unexecutedSell;
    int executedBuy;
    int executedSell;
    VolumeResult(
        this.unexecutedBuy,
        this.unexecutedSell,
        this.executedBuy,
        this.executedSell,
        );
}

VolumeResult _analyzeColumn(
    Image image,
    int x,
    int maxVolume,
    ColorRgb8 backgroundColor,
    double buyThreshold,
    double sellThreshold,
    ) {
    final segments = _findSegments(image, x, backgroundColor, buyThreshold, sellThreshold);

    // 查找分隔背景区域
    int? splitIndex;
    for (int i = 0; i < segments.length; i++) {
        if (segments[i].type == SegmentType.background) {
            splitIndex = i;
            break;
        }
    }

    // 无背景分隔时全列视为同一区域
    if (splitIndex == null) {
        final isUpper = segments.isNotEmpty &&
            segments.first.startY < image.height / 2;
        return _calculateResult(segments, maxVolume, image.height, isUpper);
    }

    // 分割上下区域
    final upperSegments = segments.takeWhile((s) => s.startY < segments[splitIndex!].startY).toList();
    final lowerSegments = segments.skip(splitIndex + 1).toList();

    return VolumeResult(
        _sumVolume(upperSegments, SegmentType.buy, maxVolume, image.height),
        _sumVolume(upperSegments, SegmentType.sell, maxVolume, image.height),
        _sumVolume(lowerSegments, SegmentType.buy, maxVolume, image.height),
        _sumVolume(lowerSegments, SegmentType.sell, maxVolume, image.height),
    );
}

class _Segment {
    final SegmentType type;
    final int startY;
    final int endY;

    _Segment(this.type, this.startY, this.endY);
}

enum SegmentType { background, buy, sell }

List<_Segment> _findSegments(
    Image image,
    int x,
    ColorRgb8 backgroundColor,
    double buyThreshold,
    double sellThreshold,
    ) {
    final segments = <_Segment>[];
    SegmentType? currentType;
    int startY = 0;

    for (int y = 0; y < image.height; y++) {
        final pixel = image.getPixel(x, y);
        final type = _detectPixelType(pixel, backgroundColor, buyThreshold, sellThreshold);

        if (currentType == null) {
            currentType = type;
            startY = y;
        } else if (type != currentType) {
            segments.add(_Segment(currentType, startY, y));
            currentType = type;
            startY = y;
        }
    }

    if (currentType != null) {
        segments.add(_Segment(currentType, startY, image.height));
    }

    return segments;
}

SegmentType _detectPixelType(
    Pixel pixel,
    ColorRgb8 backgroundColor,
    double buyThreshold,
    double sellThreshold,
    ) {
    if (pixel.r == backgroundColor.r &&
        pixel.g == backgroundColor.g &&
        pixel.b == backgroundColor.b) {
        return SegmentType.background;
    }

    if (pixel.r > pixel.g * buyThreshold &&
        pixel.r > pixel.b * buyThreshold) {
        return SegmentType.buy;
    }

    if (pixel.g > pixel.r * sellThreshold &&
        pixel.g > pixel.b * sellThreshold) {
        return SegmentType.sell;
    }

    return SegmentType.background;
}

VolumeResult _calculateResult(
    List<_Segment> segments,
    int maxVolume,
    int totalHeight,
    bool isUpper,
    ) {
    final buy = segments.where((s) => s.type == SegmentType.buy)
        .fold(0, (sum, s) => sum + _calcVolume(s, maxVolume, totalHeight));
    final sell = segments.where((s) => s.type == SegmentType.sell)
        .fold(0, (sum, s) => sum + _calcVolume(s, maxVolume, totalHeight));

    return isUpper
        ? VolumeResult(buy, sell, 0, 0)
        : VolumeResult(0, 0, buy, sell);
}

int _sumVolume(
    List<_Segment> segments,
    SegmentType type,
    int maxVolume,
    int totalHeight,
    ) {
    return segments.where((s) => s.type == type)
        .fold(0, (sum, s) => sum + _calcVolume(s, maxVolume, totalHeight));
}

int _calcVolume(_Segment segment, int maxVolume, int totalHeight) {
    return ((segment.endY - segment.startY) * maxVolume / totalHeight).round();
}
